﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using TWC = Telerik.Windows.Controls;
using Dimok;
using Dimok.FilteredView;

namespace DataGridWithFilter {
  public partial class DataGrid {
    #region Show Menus
    TWC.RadContextMenu rowMenu = null;
    public TWC.RadContextMenu RowMenu {
      get {
        if (rowMenu == null) {
          rowMenu = new Telerik.Windows.Controls.RadContextMenu();
          rowMenu.Placement = Telerik.Windows.Controls.PlacementMode.Bottom;
          rowMenu.Style = RowMenuStyle;
        }
        return rowMenu;
      }
    }
    public void ShowRowMenu(FrameworkElement fe) {
      var dc = Application.Current.Resources[DataContextHelper.GetDataContextResource(RowMenu)] as DataContextHelper;
      dc.Value = fe.GetParent<DataGridRow>().DataContext;
      TWC.RadContextMenu.SetContextMenu(fe, RowMenu);
      RowMenu.IsOpen = true;
    }
    TWC.RadContextMenu CreateColumnsMenu(List<object> items) {
      columnsMenu = new TWC.RadContextMenu();
      columnsMenu.StaysOpen = true;
      columnsMenu.Placement = Telerik.Windows.Controls.PlacementMode.Bottom;
      var menuStyle = Resources[ColumnsMenuItemStyle] as Style;
      columnsMenu.ItemContainerStyle = menuStyle;
      columnsMenu.LostFocus += new RoutedEventHandler((object sender, RoutedEventArgs e) => {
        var source = ItemsSource as IFilteredView;
        if (source != null) source.CanSort = true;
        //((TWC.RadContextMenu)sender).IsOpen = false;
      });
      columnsMenu.GotFocus += (sender, e) => {
        var source = ItemsSource as IFilteredView;
        if (source != null) source.CanSort = false;
      };
      if (items != null)
        items.ForEach(mi => columnsMenu.Items.Add(mi));
      return columnsMenu;
    }
    void ShowColumnsMenu(FrameworkElement fe) {
      #region Build Columns Menu
      if (columnsMenu == null) {
        columnsMenu = CreateColumnsMenu(null);
        #region Columns Menu
        {
          var mainMenu = new TWC.RadMenuItem() { Header = "Columns" };
          mainMenu.ItemContainerStyle = columnsMenu.ItemContainerStyle;
          columnsMenu.Items.Add(mainMenu);
          var entityType = (ItemsSource as IFilteredView).EntityType;
          var menuItems = new List<object>();
          foreach (var c in Columns) {
            var menuItem = new TWC.RadMenuItem() { Header = c.Header, IsCheckable = true };
            menuItem.Checked += new RoutedEventHandler(menuItem_Checked);
            menuItem.Unchecked += new RoutedEventHandler(menuItem_Checked);
            menuItem.Padding = new Thickness(0);
            menuItem.Margin = new Thickness(0);
            mainMenu.Items.Add(menuItem);
          }
          //var miSave = new TWC.RadMenuItem() { Header = "Save", IsCheckable = false, Foreground = new SolidColorBrush("FF8FBC8F".ToColor()) };
          {
            var sp = new StackPanel() { Orientation = Orientation.Horizontal };
            var miSave = new Button() { Content = "Save", HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5) };
            miSave.Click += new RoutedEventHandler(ColumnsSave_Click);
            sp.Children.Add(miSave);
            var miCancel = new Button() { Content = "Cancel", HorizontalContentAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5) };
            miCancel.Click += (sender, e) => columnsMenu.IsOpen = false;
            sp.Children.Add(miCancel);
            mainMenu.Items.Add(sp);
          }
        }
        #endregion
        #region Clear Filter Item
        var menuFilterClear = new TWC.RadMenuItem() { Header = "Clear Filter" };
        menuFilterClear.Click += (sender, e) => {
					ClearFilters();
          columnsMenu.IsOpen = false;
        };
        columnsMenu.Items.Add(menuFilterClear);
        #endregion
        #region Clear Sort Item
        var menuSortClear = new TWC.RadMenuItem() { Header = "Clear Sort" };
        menuSortClear.Click += (sender, e) => {
          (ItemsSource as ICollectionView).SortDescriptions.Clear();
          (ItemsSource as ICollectionView).Refresh();
          columnsMenu.IsOpen = false;
        };
        columnsMenu.Items.Add(menuSortClear);
        #endregion
      }
      #endregion
      miColumnsList.ForEach(mi => { mi.IsChecked = Columns.Single(c => c.Header + "" == mi.Header + "").Visibility == Visibility.Visible; });
      menuItem_Checked(null, null);
      try {
        TWC.RadContextMenu.SetContextMenu(fe, columnsMenu);
      } catch { }
      if (columnsMenu.UIElement != fe) CurrentContext.Post((a) => {
        var items = columnsMenu.Items.ToList();
        columnsMenu.Items.Clear();
        columnsMenu = CreateColumnsMenu(items);
        ShowColumnsMenu(fe);
      }, null);
      else
				try {
					columnsMenu.IsOpen = true;
				} catch (Exception exc) {
					MessageBox.Show(exc.Message);
				}
    }

    List<TWC.RadMenuItem> MenuItemsSort(IEnumerable<TWC.RadMenuItem> menuItems) {
      return menuItems
        .OrderByDescending(mi => mi is TWC.RadMenuItem)
        .OrderByDescending(mi => { object p; return mi.TryGetProperty("IsCheckable", out p) && (bool)p; })
        .ThenByDescending(mi => { object p; return mi.TryGetProperty("IsChecked", out p) && (bool)p; })
        .ThenBy(mi => mi.GetPropertyOrNull("Header", "Content") + "").ToList();
    }
    void ColumnsSave_Click(object sender, RoutedEventArgs e) {
      columnsMenu.IsOpen = false;
      if (false && miColumnsList.Count(mi => mi.IsChecked) == 0) {
        MessageBox.Show("Select at least one column, Jon!");
        return;
      }
      miColumnsList.ForEach(
        mi => Columns.First(c => c.Header == mi.Header).Visibility = mi.IsChecked ? Visibility.Visible : Visibility.Collapsed);
      if (VisibleColumns().Count() == 0)
        DataBoundColumns.Join(
          ProfileCurrent.GetDefaultColumns(FilteredSource.EntityType),
          dbc => dbc.Binding.Path.Path, dc => dc, (dbc, dc) => dbc).ToList().ForEach(dbc => dbc.Visibility = Visibility.Visible);

			FilteredSource.OnColumnsChanged();
    }

    TWC.RadMenuItem miColumns { get { return columnsMenu.Items[0] as TWC.RadMenuItem; } }
    List<TWC.RadMenuItem> miColumnsList { get { return miColumns.Items.OfType<TWC.RadMenuItem>().Where(mi => mi.IsCheckable).ToList(); } }

    void menuItem_Checked(object sender, RoutedEventArgs e) {
      var columnsSubMenu = columnsMenu.Items[0] as TWC.RadMenuItem;
      var items = MenuItemsSort(columnsSubMenu.Items.OfType<TWC.RadMenuItem>());
      items.Reverse();
      columnsSubMenu.Items.OfType<TWC.RadMenuItem>().ToList().ForEach(mi => columnsSubMenu.Items.Remove(mi));
      items.ForEach(mi => {
        mi.IsEnabled = filterBoxes.FirstOrDefault(tb => GetFilter(tb) == mi.Header + "" && tb.Text != "") == null;
        columnsSubMenu.Items.Insert(0, mi);
      });
    }

    void ShowFiltersMenu(Image image) {
      #region Build Menu
      if (filterMenu == null) {
        filterMenu = new Telerik.Windows.Controls.RadContextMenu();
        IEnumerable<string> filterOperators =
           from fi in typeof(FilterOperator).GetFields()
           where fi.IsLiteral
           select fi.Name;
        foreach (string name in filterOperators) {
          TWC.RadMenuItem subItem = new TWC.RadMenuItem() { Header = name, IsCheckable = true };
          //subItem.IsChecked = name == ffd.Filter1.Operator.ToString();
          //subItem.Click += new RoutedEventHandler(MenuItemClick);
          filterMenu.Items.Add(subItem);
        }
        filterMenu.Placement = Telerik.Windows.Controls.PlacementMode.Left | Telerik.Windows.Controls.PlacementMode.Top;
        filterMenu.Closed += new RoutedEventHandler((sender, e) => {
          GetFilterTextBox(((TWC.RadContextMenu)sender).UIElement).Focus();
        });
      }
      #endregion
			var propertyName = GetFilterPropertyName(GetFilterTextBox(image));
      string[] stringFilters = new[] { "Contains", "EndsWith", "IsContainedIn", "StartsWith" };
      var menuItems = filterMenu.Items.Cast<TWC.RadMenuItem>().ToList();
      menuItems.ForEach(mi => mi.Visibility = Visibility.Visible);
      if (GetFilterPropertyType(propertyName) != typeof(System.String))
        menuItems.ForEach(mi => mi.Visibility = stringFilters.Contains(mi.Header) ? Visibility.Collapsed : Visibility.Visible);
      try { TWC.RadContextMenu.SetContextMenu(image, filterMenu); } catch (NullReferenceException) { }
      if (filterMenu.UIElement != image) {
        filterMenu.Items.Clear();
        filterMenu = null;
        ShowFiltersMenu(image);
      } else filterMenu.IsOpen = true;
    }
    #endregion

  }
}
